/*
 * @Author: xiaosihan 
 * @Date: 2024-01-16 23:37:27 
 * @Last Modified by: xiaosihan
 * @Last Modified time: 2024-03-10 10:25:33
 */

import { AnimationMixer, Clock, Group, Mesh, BufferAttribute, Vector3 } from "three";
import threeLoader from "three-base/threeLoader";
import threeUtils from "three-base/threeUtils";
import { degToRad } from "three/src/math/MathUtils";

import oneFloorGLB from "./oneFloor.glb?url";
import publicMaterial from "../WindowGroup/publicMaterial";

// 1楼
export default class OneFloor extends Group {
    constructor() {
        super();

        this.loadModal(oneFloorGLB);
    }

    // 身体动作混合器
    mixer?: AnimationMixer;

    //原网格对象
    originAttributeMap = new Map<string, BufferAttribute>();

    //原对象的位置
    originPositioinMap = new Map<string, Vector3>();

    //加载完成
    loaded = false;

    // 加载身体
    async loadModal(url: string) {
        const glbObj = await threeLoader.gltfLoader.loadAsync(url);
        glbObj.scene.rotateY(degToRad(-90));
        threeUtils.scaleTo(glbObj.scene, 0.3, ["y"]);
        threeUtils.center(glbObj.scene);

        this.add(glbObj.scene);

        glbObj.scene.traverse(o => {

            const mesh = o as Mesh;
            if (mesh.isMesh) {
                if (["立方体010", "立方体006", "立方体004"].includes(mesh.name)) {
                    (mesh as Mesh).material = publicMaterial.glassMat;
                }

                const position = mesh.geometry.getAttribute("position") as BufferAttribute;
                this.originAttributeMap.set(mesh.name, position);
                mesh.geometry = mesh.geometry.clone();
                this.originPositioinMap.set(mesh.name, mesh.position.clone());
            }
            //three事件
            // mesh.userData = {
            //     cursor: "pointer",
            //     enableEvent: true,
            // };
            // mesh.addEventListener("click", e => {
            //     console.log(mesh.name);
            // });
        })

        this.mixer = new AnimationMixer(glbObj.scene);

        for (let i in glbObj.animations) {
            const animation = glbObj.animations[i];
            if (animation) {
                const action = this.mixer.clipAction(animation);
                action.play();
            }
        }

        this.setWindowNum(this.windowNum);
        this.loaded = true;
    }

    // 时钟对象
    clock = new Clock();

    updateMatrix(): void {
        const delta = this.clock.getDelta();
        if (this.mixer) {
            this.mixer.update(delta);
        }
        super.updateMatrix();
    }

    // 窗户数量
    windowNum = { east: 5, south: 5 };

    // 根据窗户数量设置模型的宽高
    setWindowNum(windowNum: { east: number, south: number }) {
        this.windowNum = {
            east: Math.max(5, windowNum.east),
            south: Math.max(5, windowNum.south)
        };

        this.traverse(o => {
            const mesh = o as Mesh;

            if (mesh.isMesh) {

                const originPosition = this.originAttributeMap.get(mesh.name)!;
                const position = mesh.geometry.getAttribute("position")!;

                if (["楼层", "隔层"].includes(mesh.name)) {
                    //更具窗户数更新网格

                    const offset = {
                        east: (8 - this.windowNum.east) * 0.002,
                        south: (8 - this.windowNum.south) * 0.002,
                    }

                    for (let i = 0; i < originPosition.count; i++) {

                        if (originPosition.getX(i) >= 0.01) {
                            position.setX(i, originPosition.getX(i) - offset.south);
                        } else if (originPosition.getX(i) <= -0.01) {
                            position.setX(i, originPosition.getX(i) + offset.south);
                        }

                        if (originPosition.getZ(i) >= 0) {
                            position.setZ(i, originPosition.getZ(i) - (offset.east * 2));
                        } else if (originPosition.getZ(i) <= 0) {
                            // position.setZ(i, originPosition.getZ(i) + (offset * 2));
                        }
                    }

                    // } else if (["立方体010", "立方体006", "立方体004", "立方体003", "立方体005", "立方体007"].includes(mesh.name)) {
                    // const originPosition = this.originPositioinMap.get(mesh.name);
                    // if (originPosition) {
                    //     mesh.position.copy(originPosition);
                    //     mesh.position.z += offset;
                    // }
                } else {
                    // const originPosition = this.originPositioinMap.get(mesh.name);
                    // if (originPosition) {
                    //     mesh.position.copy(originPosition);
                    //     mesh.position.z += offset;
                    // }
                }

                position.needsUpdate = true;
                mesh.geometry.computeBoundingBox();
            }


            // 更具窗户的数量计算网格的偏移量
            const offset = {
                east: (8 - this.windowNum.east) * 0.14,
                south: (8 - this.windowNum.south) * 0.14,
            }
            this.position.setX(-offset.east);

        });

    }

}